1 00:00:00,620 --> 00:00:01,640 Welcome back. 2 00:00:01,640 --> 00:00:05,240 In this lecture we're going to take a look at some built in types. 3 00:00:05,240 --> 00:00:11,450 Roblox Liu has three built in types that exist for the type engine, and these types are any unknown 4 00:00:11,450 --> 00:00:12,530 and never. 5 00:00:12,530 --> 00:00:17,090 Now you've seen me talk about any earlier in the course, and in this lecture, we're going to actually 6 00:00:17,090 --> 00:00:19,550 look at the true form of any. 7 00:00:19,550 --> 00:00:21,890 I'm going to create a variable here. 8 00:00:22,310 --> 00:00:24,080 I'm going to call it my var. 9 00:00:25,090 --> 00:00:29,290 And I'm not going to give it a value, nor am I going to give it a type annotation. 10 00:00:29,320 --> 00:00:35,290 Now, when I type out the name of this variable, you'll see that this letter here says a. 11 00:00:35,320 --> 00:00:41,020 Now, I told you that this was any in a previous lecture, but in actuality, that's not the true form 12 00:00:41,020 --> 00:00:41,590 of any. 13 00:00:41,590 --> 00:00:47,620 While we can set this variable to be whatever we'd like, such as we could set it to be a string. 14 00:00:48,160 --> 00:00:53,560 Once we give it this value, it's going to update the type of this variable to be of the value that 15 00:00:53,560 --> 00:00:55,390 we set it to be, which was a string. 16 00:00:55,390 --> 00:00:58,570 And now this variable is going to forever be of the type string. 17 00:00:58,570 --> 00:01:03,910 So if I try to set it to be another type such as a boolean, we're going to get a red underline here. 18 00:01:03,910 --> 00:01:07,630 And that's because we can't convert this type boolean into the type string. 19 00:01:07,630 --> 00:01:10,900 So we originally initialized it to have no value. 20 00:01:10,900 --> 00:01:12,730 And then we set the value to the string. 21 00:01:12,730 --> 00:01:14,800 And it gave it the type of string. 22 00:01:14,800 --> 00:01:18,370 And now this variable is going to forever be of the type string. 23 00:01:18,370 --> 00:01:23,620 However, if I want to be able to override this variable to whatever I'd like, then this is where the 24 00:01:23,620 --> 00:01:25,660 real any type comes into play. 25 00:01:25,660 --> 00:01:31,300 The any type is a special kind of type that allows itself to be used as an arbitrary type that can stand 26 00:01:31,300 --> 00:01:32,110 for anything. 27 00:01:32,110 --> 00:01:36,850 This type allows us to skip the process of type refinement that is needed for the type engine to figure 28 00:01:36,850 --> 00:01:39,100 out what exactly the type of a variable is. 29 00:01:39,100 --> 00:01:42,160 And of course, we're going to take a look at type refinement in a little bit. 30 00:01:42,160 --> 00:01:47,170 So basically when we create a new variable and we don't assign it any value, it can inherit any value 31 00:01:47,170 --> 00:01:48,280 and doesn't have a type. 32 00:01:48,280 --> 00:01:54,070 But once it's assigned a value like we did right here, the type of that value is set for the variable. 33 00:01:54,070 --> 00:01:58,780 If we want to continually override the variable, then we have to explicitly set the type of this variable 34 00:01:58,780 --> 00:02:00,400 to be of the type any. 35 00:02:00,400 --> 00:02:03,130 And now we have that red underline disappear. 36 00:02:03,130 --> 00:02:06,550 And that's because my var is going to forever be of the type any. 37 00:02:06,550 --> 00:02:10,480 It's no longer a string or a boolean, but instead it is of the type. 38 00:02:10,480 --> 00:02:15,280 Any the any type is just basically an opt out of the type system entirely. 39 00:02:15,280 --> 00:02:20,500 So if we don't want to have to bother with a variable being underlined when we override its value while 40 00:02:20,500 --> 00:02:25,210 we're in the strict type inferencing mode, then we can just set it to any and then it opts out this 41 00:02:25,210 --> 00:02:29,710 variable to be of the type checking system, so we can set it to whatever we'd like, and we don't get 42 00:02:29,710 --> 00:02:31,090 any red underlines. 43 00:02:31,270 --> 00:02:35,800 Our next type is the unknown type, and this one is going to be a little more interesting as it's considered 44 00:02:35,800 --> 00:02:37,900 to be a top type. 45 00:02:37,900 --> 00:02:42,520 Now, a top type means that this is a union of every other type in our game, and for us to be able 46 00:02:42,520 --> 00:02:46,990 to figure out what the exact type of a variable is, we have to use type refinement. 47 00:02:46,990 --> 00:02:52,060 Or basically we got to use if statements and some functions to let studio know exactly what the type 48 00:02:52,060 --> 00:02:53,320 of a variable is. 49 00:02:53,620 --> 00:02:58,180 So I'm going to create a function here and it's going to be called get unknown. 50 00:02:59,870 --> 00:03:04,310 And inside of this function we're going to do a little bit of some syntax magic. 51 00:03:04,310 --> 00:03:06,740 And I'm going to return. 52 00:03:06,740 --> 00:03:08,570 And then I'm going to put an if statement here. 53 00:03:08,570 --> 00:03:16,400 So if math dot random is greater than 0.5 then we're going to return a string of some string. 54 00:03:16,940 --> 00:03:18,470 Otherwise five. 55 00:03:18,470 --> 00:03:24,560 And what this does is that we're returning some string in case math dot random is greater than 0.5. 56 00:03:24,560 --> 00:03:26,660 Otherwise we're returning five. 57 00:03:26,660 --> 00:03:30,410 And as you can see, we don't have to put an end statement here because we're using a little bit of 58 00:03:30,410 --> 00:03:32,060 some syntax magic. 59 00:03:32,570 --> 00:03:37,460 Now we can denote this function as returning the type unknown. 60 00:03:37,460 --> 00:03:40,700 Because we're not going to have any idea what this function is going to return. 61 00:03:40,700 --> 00:03:42,620 It could return a string or it could return a number. 62 00:03:42,620 --> 00:03:43,550 We don't know. 63 00:03:43,850 --> 00:03:48,770 And now that means, because we've set the return of this function to be of the unknown type, when 64 00:03:48,770 --> 00:03:53,720 we get the value that gets returned from this function, a is going to be of the type unknown. 65 00:03:53,720 --> 00:03:57,080 And that means we cannot set the type annotation for this variable. 66 00:03:57,080 --> 00:04:00,560 So if I try to set it to a string, we're going to get a problem here okay. 67 00:04:00,560 --> 00:04:03,590 Because we can't convert the type unknown into string. 68 00:04:03,590 --> 00:04:08,420 Same thing goes for if we had another variable and we try to set it to be a number equal to the get 69 00:04:08,420 --> 00:04:12,140 unknown function, again, we're going to get an error and it's even not going to work. 70 00:04:12,140 --> 00:04:16,880 If we had a variable with a union type and we set it to either a string or a number. 71 00:04:16,880 --> 00:04:18,800 So if we do this. 72 00:04:19,420 --> 00:04:21,610 We're still going to get a red underline. 73 00:04:21,610 --> 00:04:23,170 How do we solve this conundrum? 74 00:04:23,170 --> 00:04:25,870 Well, that's where type refinement comes into play. 75 00:04:25,870 --> 00:04:28,900 We have to refine the type that gets returned from this function. 76 00:04:28,900 --> 00:04:31,240 For us to be able to figure out what exactly it is. 77 00:04:31,240 --> 00:04:33,820 And we use that by using three different functions. 78 00:04:33,820 --> 00:04:39,670 One function is assert, one function is type, and the other function is type of. 79 00:04:39,670 --> 00:04:44,800 Now you might have heard of these functions if you were in my previous beginner's lecture, but if you 80 00:04:44,800 --> 00:04:47,470 haven't then I'm going to explain them right now for you. 81 00:04:47,740 --> 00:04:48,160 All right. 82 00:04:48,160 --> 00:04:53,290 So first off the assert function is a function that we can use to manually throw errors. 83 00:04:53,290 --> 00:04:57,460 If a given argument to the function is falsy, we can give it any value. 84 00:04:57,460 --> 00:05:02,650 And it's going to check if the value is false or nil, and if so it can throw a custom error message 85 00:05:02,650 --> 00:05:03,310 we give it. 86 00:05:03,310 --> 00:05:07,750 It's just like the error function, but it checks if a value is falsy for us if we need that kind of 87 00:05:07,750 --> 00:05:08,560 functionality. 88 00:05:08,560 --> 00:05:11,830 So I'm going to create a variable here called some bool. 89 00:05:11,830 --> 00:05:13,690 And I'm going to set it to false. 90 00:05:13,690 --> 00:05:18,580 And then I can call the assert function and pass some bool to this function. 91 00:05:18,580 --> 00:05:21,130 And then I can give it a custom error message to throw out. 92 00:05:21,130 --> 00:05:28,780 In case this variable or value we pass to the function is falsy such as the value was false, and since 93 00:05:28,780 --> 00:05:32,500 some bool is false, this error message should get printed into the console. 94 00:05:32,500 --> 00:05:33,850 So if we run the game. 95 00:05:35,380 --> 00:05:38,920 We see that the value was false. 96 00:05:38,950 --> 00:05:39,850 Very nice. 97 00:05:40,150 --> 00:05:45,970 Now, just a quick note is that the assert function can be costly if you try to use string concatenation 98 00:05:45,970 --> 00:05:49,210 or string formatting in the second parameter section here. 99 00:05:49,210 --> 00:05:53,620 And that's because string concatenation and formatting is a costly thing to calculate for computers, 100 00:05:53,620 --> 00:05:57,400 especially in Lua, when we try to pass it as a second parameter. 101 00:05:57,400 --> 00:06:02,170 If you need to use string formatting or string concatenation for error messages, then it's probably 102 00:06:02,170 --> 00:06:07,120 better to use an if statement to check whether a value is falsy, and then just use the error function 103 00:06:07,120 --> 00:06:07,540 instead. 104 00:06:07,540 --> 00:06:10,660 For your string concatenation and string formatting needs. 105 00:06:10,660 --> 00:06:15,610 It's actually a lot more performant, and somebody did some testing and found that it's much faster 106 00:06:15,610 --> 00:06:20,740 to use if statements in the error function than it is to use the assert function with string concatenation 107 00:06:20,740 --> 00:06:21,430 and formatting. 108 00:06:21,430 --> 00:06:23,440 So just keep that in mind. 109 00:06:23,440 --> 00:06:27,580 Now moving on we're going to look at the type and type of functions. 110 00:06:27,580 --> 00:06:31,450 So what is the difference between the type and type of functions. 111 00:06:31,450 --> 00:06:37,120 Well the type function is a function that's built into Lua itself that tells you the primitive type 112 00:06:37,120 --> 00:06:38,980 of a value that you pass to the function. 113 00:06:38,980 --> 00:06:44,200 So if you pass a string, it's going to return a string back to you that tells you the name of the type, 114 00:06:44,200 --> 00:06:49,870 such as string, or if it's a number, it's going to return a string back to you that says number and 115 00:06:49,870 --> 00:06:50,500 so on. 116 00:06:50,500 --> 00:06:52,810 So that's the purpose of the type function. 117 00:06:52,810 --> 00:06:57,100 Now the type of function is specific here to Roblox, Lua you. 118 00:06:57,100 --> 00:07:01,870 And that's because it's able to tell you the type of the custom data types in Roblox. 119 00:07:01,870 --> 00:07:07,180 So for example, if you try to pass a vector data type to the type function, it's going to return you 120 00:07:07,180 --> 00:07:09,190 a string that just says user data. 121 00:07:09,190 --> 00:07:15,310 And that's because user data is another primitive type in Lua where people can make their own custom 122 00:07:15,310 --> 00:07:21,730 types, which is what Roblox does with their own custom types like vectors, parts, and so on. 123 00:07:21,730 --> 00:07:26,440 So if you need to specifically check the type of a Roblox data type, that's where you would use the 124 00:07:26,440 --> 00:07:27,880 type of function. 125 00:07:29,170 --> 00:07:31,840 So let's go ahead and demonstrate these functions here real quick. 126 00:07:31,840 --> 00:07:33,610 I'm going to create a vector here. 127 00:07:33,610 --> 00:07:38,050 I'll just call it some vector equal to a vector two dot new. 128 00:07:38,050 --> 00:07:39,850 And we'll just pass zero and zero. 129 00:07:39,850 --> 00:07:43,990 And then I'm also going to create a variable called some string and just set it to high. 130 00:07:43,990 --> 00:07:48,940 And then what we could do is we could print out what the type of some vector is here in the console 131 00:07:48,940 --> 00:07:53,620 using the type function, as well as print out the type of some string. 132 00:07:53,620 --> 00:07:58,210 And then let me comment this out real quick so our script does not error. 133 00:07:58,210 --> 00:08:02,620 So what we should expect to print here is that it should print out user data. 134 00:08:02,620 --> 00:08:05,470 And what we should expect to print out here is string. 135 00:08:05,470 --> 00:08:06,880 So if we run our game. 136 00:08:07,630 --> 00:08:10,840 As you can see, we get user data and we get string. 137 00:08:10,930 --> 00:08:16,300 Now, if we wanted to specifically know whether or not this value was a vector two, then that's where 138 00:08:16,300 --> 00:08:18,670 we would have to use the type of function. 139 00:08:18,670 --> 00:08:25,210 So if I go ahead and print the type of our some vector, it should print vector two. 140 00:08:26,000 --> 00:08:26,750 And there we go. 141 00:08:26,750 --> 00:08:30,710 We get the custom Roblox data type by using the type of function. 142 00:08:30,830 --> 00:08:35,810 And again, this is the only difference between the type and the type of functions. 143 00:08:36,320 --> 00:08:42,860 Now, because we know the type and type of functions, we can use them for type refinement by narrowing 144 00:08:42,860 --> 00:08:49,010 down what the type of a variable is in a specific context, we can avoid errors and make our code easier 145 00:08:49,010 --> 00:08:49,940 to understand. 146 00:08:49,940 --> 00:08:56,030 So if we want to figure out what exactly the type is of the value that gets returned from our get unknown 147 00:08:56,030 --> 00:09:00,020 function, then we can use the type or type of functions. 148 00:09:00,470 --> 00:09:05,630 So let me create a variable here I'm going to call it refinement example. 149 00:09:05,630 --> 00:09:07,730 And we're going to set it to get unknown. 150 00:09:07,730 --> 00:09:11,450 And currently our refinement example is of the type unknown. 151 00:09:11,450 --> 00:09:17,720 So how the heck do we figure out without getting errors in our code or like these red underlines here. 152 00:09:17,720 --> 00:09:19,490 What's the type of refinement? 153 00:09:19,490 --> 00:09:20,360 Example is. 154 00:09:20,360 --> 00:09:22,520 Well we can use the type of function. 155 00:09:22,520 --> 00:09:29,210 So if type of refinement example is equal to the string let's say string. 156 00:09:30,110 --> 00:09:35,210 Then in this context, in this indention here in this block of code right. 157 00:09:35,210 --> 00:09:38,030 This is the context for our script. 158 00:09:38,030 --> 00:09:41,540 We know that refinement example has to be a string. 159 00:09:41,540 --> 00:09:46,760 And the type checking engine is automatically going to infer that for us that's how we're refining the 160 00:09:46,760 --> 00:09:47,510 type here. 161 00:09:47,510 --> 00:09:49,400 We can also do the same. 162 00:09:49,400 --> 00:09:55,040 Else if the type of refinement example is equal to a number. 163 00:09:55,640 --> 00:09:59,780 Then in this particular context we know refinement example is a number, right? 164 00:09:59,780 --> 00:10:01,040 It's that simple. 165 00:10:01,040 --> 00:10:07,640 Now if we were to go and put an else statement here, let's say for some reason refinement example wasn't 166 00:10:07,640 --> 00:10:10,970 a string or a number, which is impossible. 167 00:10:10,970 --> 00:10:15,980 Then this is where refinement example would inhibit the type of never. 168 00:10:15,980 --> 00:10:21,170 Now the never type is considered the bottom type, meaning that there will never be a value in Lua that 169 00:10:21,170 --> 00:10:22,550 has the type of never. 170 00:10:22,550 --> 00:10:27,620 When we are in a context in Lua where we have refined a variable to a point where it has no possible 171 00:10:27,620 --> 00:10:31,760 type, like right here, then it is of the type never. 172 00:10:32,030 --> 00:10:35,600 Now, I don't want you to be so concerned about these three built in types. 173 00:10:35,600 --> 00:10:39,890 You'll likely never use them except for maybe any and unknown. 174 00:10:39,890 --> 00:10:44,900 This lecture is just to expose you to these built in types, and considering many other developers never 175 00:10:44,900 --> 00:10:47,240 use them, I don't expect you to either. 176 00:10:47,780 --> 00:10:52,370 So again, before I end this lecture, I want to be fully and explicitly clear once more. 177 00:10:52,370 --> 00:10:55,370 That type annotation is not required in our code. 178 00:10:55,370 --> 00:11:00,860 It exists simply to help us and other developers understand the types of variables, what types are 179 00:11:00,860 --> 00:11:05,330 required for functions, and what the type is of return values from functions. 180 00:11:05,330 --> 00:11:09,680 We're going to continue learning more about types in the next lectures, so go ahead and try to wrap 181 00:11:09,680 --> 00:11:11,660 up everything in your mind from this lecture. 182 00:11:11,660 --> 00:11:13,940 And I'm going to see you in the next one.